#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <stddef.h>

/* Node for linked list or binary tree. */
typedef struct Node {
	char *filename;
	struct Node *left;
	struct Node *right;
} Node;

#define ARG_MAX 10
#define CHAR_MAX 100

void compute(int i, int writepos, int *pipes, int pipeSize, int numCmd);
void closePipes(int *pipes, int pipeSize);
void parse(char *string);
char* removeSpace(char *token);

int main(int argc, char **argv) {
	// Create array to store user command and arguments
	char string[CHAR_MAX];
	fgets(string, sizeof string, stdin);
	parse(string);
	
	/*
	int status;
	int numCmd = 1;
	int pipeSize = (numCmd - 1) * 2;
	int pipes[pipeSize];
	for (int i = 0; i < pipeSize; i += 2) {
		if (pipe(pipes + i) == -1) {
			printf("Error in creating pipes.\n"); exit(1);
		}
	}
	compute(0, 1, pipes, pipeSize, numCmd);
	closePipes(pipes, pipeSize);
	for (int i = 0; i < numCmd; i++) {
		waitpid(-1, &status, 0);
	}
	*/
	exit(0);
}

void compute(int i, int writepos, int *pipes, int pipeSize, int numCmd) {
	if (i < numCmd) {
		pid_t pid = fork();
		if (pid == 0) {
			// Case 1: First command
			if (i == 0) {
				dup2(pipes[writepos], 1);
				closePipes(pipes, pipeSize);
				// ls command
				char *lsArray[2];
				lsArray[0] = "/bin/ls";
				lsArray[1] = (char *) 0;
				execv(lsArray[0], lsArray);
			}
			// Case 2: Last command
			else if (i == (numCmd - 1)) {
				dup2(pipes[pipeSize - 2], 0);
				closePipes(pipes, pipeSize);
				// wc command
				char *wcArray[2];
				wcArray[0] = "/usr/bin/wc";
				//wcArray[0] = "/bin/less";
				wcArray[1] = (char *) 0;
				execv(wcArray[0], wcArray);
			}
			// Case 3: Middle command
			else {
				dup2(pipes[writepos - 3], 0);
				dup2(pipes[writepos], 1);
				closePipes(pipes, pipeSize);
				// grep command
				char *grepArray[3];
				grepArray[0] = "/bin/grep";
				grepArray[1] = "h";
				grepArray[2] = (char *) 0;
				execv(grepArray[0], grepArray);
			}
		}
		else {
			compute(i+1, writepos+2, pipes, pipeSize, numCmd);
		}
	}
}

void closePipes(int *pipes, int pipeSize) {
	for (int i = 0; i < pipeSize; i++) {
		close(pipes[i]);
	}
}

void parse(char *string) {
	//printf("%s", string);
	char *token[80];
	token[0] = strtok(string, "|");
	
	int i = 0;
	while (token[i] != NULL) {
		i++;
		token[i] = strtok(NULL, "|");
	}
	
	// Token is a pointer to a char array
	for (int j = 0; j <= i-1; j++) {
		//removeSpace(token[j]);
		strcpy(token[j], removeSpace(token[j]));
		//printf("%s\n", token[j]);
	}
}

char* removeSpace(char *token) {
	char str2[100];
	int i = 0;
	char *p = token;
	while(*p) {
		if(*p != ' ') {
			str2[i++] = *p;
		}
		p++;
	}
	str2[i] = 0;
	strcpy(token, str2);
	//printf("%s\n", token);
	return(token);
}
